﻿using System.Collections.Generic;
using UnityEngine;
using WorldMapNew;
using Yoozoo.Gameplay.RTS;
using Random = UnityEngine.Random;

public class MapChunckTrafficCar : MonoBehaviour
{
    // 汽车参数
    public GameObject[] wheels;
    float endPosDis = 0.001f;

    public float _speed = 0;
    public bool isMonsterStop = false;
    public float _oldSpeed = 0;
    float _curAngle = -1;

    Vector3 _offset;

    // 线路相关
    int curLineIdx = 0;
    int curRoadIdx = 0;
    Vector3 startPos;
    Vector3 endPos;
    Vector2 endPosV2 = Vector2.zero;
    Vector2 curPosV2 = Vector2.zero;
    TrafficLineData curLineData;
    TrafficLineData nextLineData;

    TrafficLineDataOne curLineAllData;
    MapChunckTrafficTileRunData curTileRunData;
    BoxCollider box;
    private Vector3 currentPos;
    int _tileIdx = 0;

    private float _lastRayCastTime = 0;

    // debug
    List<Vector3> movePoint;
    public bool isDebug = false;
    bool isWaitLight = false;

    public void SetMapChunckLineRunData(MapChunckTrafficTileRunData runData, TrafficLineDataOne lineData,
        Vector3 offset, int tileIdx)
    {
        // 解析路线
        curLineAllData = lineData;
        curTileRunData = runData;
        curLineIdx = 0;
        isWaitLight = false;
        _offset = offset;
        _tileIdx = tileIdx;
        if (lineData.trafficLineDataOne.Count > 0)
        {
            curLineData = lineData.trafficLineDataOne[curLineIdx];
            nextLineData = lineData.trafficLineDataOne[curLineIdx + 1];

            MapChunckTrafficPointRunData pointRunData =
                curTileRunData.trafficNodeDatas[curLineData.nodeId][curLineData.pointId];
            startPos = pointRunData.pointVec3;
            if (pointRunData.roadPointDatas != null &&
                pointRunData.roadPointDatas.ContainsKey(nextLineData.pointId)) // 说明存在中间点
            {
                curRoadIdx = 0;
                endPos = pointRunData.roadPointDatas[nextLineData.pointId].roadPoints[curRoadIdx];
                //Debug.Log(string.Format("[小车] 起始点 {0}|{1} 下一个点（中间点）{2}|{3} - {4} ", curLineData.nodeId, curLineData.pointId, nextLineData.nodeId, nextLineData.pointId, curRoadIdx));
            }
            else
            {
                curRoadIdx = -1;
                endPos = curTileRunData.trafficNodeDatas[nextLineData.nodeId][nextLineData.pointId].pointVec3;
                //Debug.Log(string.Format("[小车] 起始点 {0}|{1} 下一个点（坐标点）{2}|{3} ", curLineData.nodeId, curLineData.pointId, nextLineData.nodeId, nextLineData.pointId));
            }

            _speed = Random.Range(9, 24) * 0.05f;
            _oldSpeed = _speed;
            currentPos = startPos + _offset;
            transform.position = currentPos;
#if UNITY_EDITOR
            if (isDebug)
            {
                movePoint = new List<Vector3>();
                movePoint.Add(currentPos);
                movePoint.Add(endPos + _offset);
            }
#endif

            // 设置角度
            float angleEnd = GetAngle(startPos, endPos) + 90;
            transform.eulerAngles = Vector3.up * angleEnd;
        }
    }

    private int BatchNum = 0;

    public void CheckMove(bool isInCamera, float deltaTime)
    {
        bool bFind = false;
        if (isInCamera)
        {
            if (box == null) box = gameObject.GetComponent<BoxCollider>();
            RaycastHit[] res = Physics.BoxCastAll(box.center + transform.position, box.size * 0.5f, Vector3.down,
                Quaternion.Euler(0, -1, 0), 100);

            for (int i = 0; i < res.Length; i++)
            {
                GameObject obj = res[i].collider.gameObject;
                if (obj == gameObject) continue;
                MarchMono march = obj.GetComponent<MarchMono>();
                if (march)
                {
                    if (march.eClientMarchType == EClientMarchType.Monster && isMonsterStop == false)
                        continue; // 判断野怪碰撞
                    if (_speed > 0) _oldSpeed = _speed;
                    _speed = 0;
                    bFind = true;
                    break;
                }

                MapChunckTrafficCar car = obj.GetComponent<MapChunckTrafficCar>();
                if (car)
                {
                    _speed = car._speed;
                    bFind = true;
                    break;
                }
            }
        }

        if (!bFind)
        {
            _speed = _oldSpeed;
        }
    }

    // 
    public void Move(float deltaTime)
    {
        bool bNext = false;
        // 判断到达线段终点
        Vector3 curEndPos = endPos + _offset;
        endPosV2.x = curEndPos.x;
        endPosV2.y = curEndPos.z;
        curPosV2.x = transform.position.x;
        curPosV2.y = transform.position.z;

        var des = Vector2.Distance(curPosV2, endPosV2);
        //移向目标
        curPosV2 = Vector2.MoveTowards(curPosV2, endPosV2, deltaTime * _speed);
        //currentPos.y = 0;// 这里要清除y值因为渐进可能的增量 不然小车跑一段时间就会有y值变化


        Vector3 pos = transform.position;
        pos.x = curPosV2.x;
        pos.y = 0;
        pos.z = curPosV2.y;
        transform.position = pos;
        bNext = des < endPosDis;

        if (bNext)
        {
            ModeNextPoint();
        }
    }

    private float GetAngle(Vector3 a, Vector3 b)
    {
        b.x -= a.x;
        b.z -= a.z;

        float deltaAngle = 0;
        if (b.x == 0 && b.z == 0)
        {
            return 0;
        }
        else if (b.x > 0 && b.z > 0)
        {
            deltaAngle = 0;
        }
        else if (b.x > 0 && b.z == 0)
        {
            return 90;
        }
        else if (b.x > 0 && b.z < 0)
        {
            deltaAngle = 180;
        }
        else if (b.x == 0 && b.z < 0)
        {
            return 180;
        }
        else if (b.x < 0 && b.z < 0)
        {
            deltaAngle = -180;
        }
        else if (b.x < 0 && b.z == 0)
        {
            return -90;
        }
        else if (b.x < 0 && b.z > 0)
        {
            deltaAngle = 0;
        }

        float angle = Mathf.Atan(b.x / b.z) * Mathf.Rad2Deg + deltaAngle;
        return angle;
    }


    public void ModeNextPoint()
    {
        if (!isWaitLight) // 等待信号灯的时候 不移动路点idx
        {
            // 开始点一定是当前endPos
            startPos = endPos;
            // 找下一个中间点
            MapChunckTrafficPointRunData pointRunData =
                curTileRunData.trafficNodeDatas[curLineData.nodeId][curLineData.pointId];

            if (curRoadIdx >= 0 && curRoadIdx < pointRunData.roadPointDatas[nextLineData.pointId].roadPoints.Count - 1)
            {
                curRoadIdx++;
                endPos = pointRunData.roadPointDatas[nextLineData.pointId].roadPoints[curRoadIdx];
                //Debug.Log(string.Format("[小车] 移动 3 {0}|{1} 下一个点（中间点）{2}|{3} - {4} ", curLineData.nodeId, curLineData.pointId, nextLineData.nodeId, nextLineData.pointId, curRoadIdx));
#if UNITY_EDITOR
                if (isDebug)
                {
                    movePoint.Add(endPos + _offset);
                }
#endif
                // 经过一个中间点也要改变方向
                float angleEnd = GetAngle(startPos, endPos) + 90;
                transform.eulerAngles = Vector3.up * angleEnd;
                return;
            }
            // 找一下个路点
            else if (curLineIdx < curLineAllData.trafficLineDataOne.Count - 2)
            {
                curLineIdx++;
            }
            else
                // 从路线起始点开始
            {
                curLineIdx = 0;
                //Debug.Log(string.Format("[小车] 循环结束 "));
#if UNITY_EDITOR
                if (isDebug)
                {
                    movePoint.Clear();
                    movePoint.Add(startPos + _offset);
                }
#endif
            }
        }

        curLineData = curLineAllData.trafficLineDataOne[curLineIdx];
        nextLineData = curLineAllData.trafficLineDataOne[curLineIdx + 1];
        // 判断当前红绿灯处可以切换路点
        bool bCanMove = true;
        if (curLineData.nodeId == nextLineData.nodeId) // 同路口才需要判断路灯
        {
            int side1 = (int) Mathf.Ceil(curLineData.pointId / 10);
            int side2 = (int) Mathf.Ceil(nextLineData.pointId / 10);
            int state = DynamicLayerMgr.worldEntry.GetLightState(_tileIdx, curLineData.nodeId, side1,
                (side1 + 2) % 4); // 如果是 1 -> 4 其实是查找 1 -> 3 方向的路灯
            //Debug.Log(string.Format("[小车] 判断红绿灯 {0}|{1} -> {2}|{3} State {4} ", curLineData.nodeId, curLineData.pointId, nextLineData.nodeId, nextLineData.pointId, state));
            if (state == 0) // 绿灯
            {
            }
            else // 黄灯 或者 红点
            {
                bCanMove = side1 + 1 == side2; // 转向条件  1 -> 2 +1是右转 1 -> 3 +2直行 1（5） -> 4 -1是左转
            }
        }

        if (bCanMove) MoveNextNode();
        isWaitLight = bCanMove == false;
    }

    public void MoveNextNode()
    {
        MapChunckTrafficPointRunData pointRunData =
            curTileRunData.trafficNodeDatas[curLineData.nodeId][curLineData.pointId];
        if (pointRunData.roadPointDatas != null &&
            pointRunData.roadPointDatas.ContainsKey(nextLineData.pointId)) // 说明存在中间点
        {
            curRoadIdx = 0;
            endPos = pointRunData.roadPointDatas[nextLineData.pointId].roadPoints[curRoadIdx];
            //Debug.Log(string.Format("[小车] 移动 1 {0}|{1} 下一个点（中间点）{2}|{3} - {4} ", curLineData.nodeId, curLineData.pointId, nextLineData.nodeId, nextLineData.pointId, curRoadIdx));
        }
        else
        {
            curRoadIdx = -1;
            endPos = curTileRunData.trafficNodeDatas[nextLineData.nodeId][nextLineData.pointId].pointVec3;
            //Debug.Log(string.Format("[小车] 移动 2 {0}|{1} 下一个点（坐标点）{2}|{3} ", curLineData.nodeId, curLineData.pointId, nextLineData.nodeId, nextLineData.pointId));
        }
#if UNITY_EDITOR
        if (isDebug)
        {
            movePoint.Add(endPos + _offset);
        }
#endif
        // 设置角度
        float angleEnd = GetAngle(startPos, endPos) + 90;
        transform.eulerAngles = Vector3.up * angleEnd;
    }
#if UNITY_EDITOR
    void OnDrawGizmos()
    {
        if (isDebug && movePoint != null && movePoint.Count > 1)
        {
            Gizmos.color = Color.red;
            for (int i = 0; i < movePoint.Count - 1; i++)
            {
                Gizmos.DrawLine(movePoint[i], movePoint[i + 1]);
            }
        }
    }
#endif
    public void OnReset()
    {
#if UNITY_EDITOR
        movePoint?.Clear();
#endif
        isDebug = false;
        if (box)
        {
            box.enabled = false;
        }
    }

    public void OnCreated()
    {
        box = GetComponent<BoxCollider>();
        if (box)
        {
            box.enabled = TrafficSystem.IsCarCheck;
        }
    }
}